package com.zscat.mallplus.ums.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zscat.mallplus.exception.ApiMallPlusException;
import com.zscat.mallplus.exception.BusinessMallException;
import com.zscat.mallplus.single.ApiBaseAction;
import com.zscat.mallplus.sys.entity.SysUser;
import com.zscat.mallplus.sys.mapper.SysAppletSetMapper;
import com.zscat.mallplus.sys.mapper.SysUserMapper;
import com.zscat.mallplus.ums.entity.SysAppletSet;
import com.zscat.mallplus.ums.entity.UmsAdminMember;
import com.zscat.mallplus.ums.entity.UmsMember;
import com.zscat.mallplus.ums.mapper.UmsAdminMemberMapper;
import com.zscat.mallplus.ums.mapper.UmsMemberMapper;
import com.zscat.mallplus.ums.service.IUmsAdminMemberService;
import com.zscat.mallplus.ums.service.IUmsMemberService;
import com.zscat.mallplus.ums.service.RedisService;
import com.zscat.mallplus.utils.*;
import com.zscat.mallplus.vo.ApiContext;
import com.zscat.mallplus.vo.AppletLoginParam;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author mallplus
 * @since 2019-04-19
 */
@Slf4j
@Service
public class UmsAdminMemberServiceImpl extends ServiceImpl<UmsAdminMemberMapper, UmsAdminMember> implements IUmsAdminMemberService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminMemberServiceImpl.class);
    @Resource
    private UmsAdminMemberMapper memberMapper;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Value("${redis.key.prefix.authCode}")
    private String REDIS_KEY_PREFIX_AUTH_CODE;
    @Value("${authCode.expire.seconds}")
    private Long AUTH_CODE_EXPIRE_SECONDS;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Value("${aliyun.sms.expire-minute:1}")
    private Integer expireMinute;
    @Value("${aliyun.sms.day-count:30}")
    private Integer dayCount;

    @Resource
    private SysAppletSetMapper appletSetMapper;

    private OkHttpClient okHttpClient = new OkHttpClient();

    @Resource
    private ApiContext apiContext;

    @Override
    public Map<String, Object> loginByWeixinPage(String code) throws BusinessMallException {
        String wxH5Appid = "wx76bd72bfc117cbaf";
        String wxH5Secret = "4870b9b25e73848d6f74920c566787b3";
        //H5 微信公众号网页登录
        LOGGER.info("appid:{},appsecret:{}", wxH5Appid, wxH5Secret);
        try {
            String json = okHttpClient.newCall(
                    new Request.Builder().url("https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                            + wxH5Appid + "&secret=" + wxH5Secret + "&code=" + code + "&grant_type=authorization_code").build()).execute().body().string();
            com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(json);
            Integer errcode = jsonObject.getInteger("errcode");
            LOGGER.info("授权信息:{}", JSON.toJSONString(jsonObject));
            Map<String, Object> resultObj = new HashMap<>();
            String token = null;
            if (errcode == null || errcode == 0) {
                String openid = jsonObject.getString("openid");
                QueryWrapper qw = new QueryWrapper();
                qw.eq("weixin_openid", openid);
                List<UmsAdminMember> userDOS = memberMapper.selectList(qw);
                if (!CollectionUtils.isEmpty(userDOS)) {
                    //若用户已经注册，则直接返回用户
                    UmsAdminMember member = userDOS.get(0);
                    token = jwtTokenUtil.generateToken(member.getUsername());
                    resultObj.put("userId", member.getId());
                    resultObj.put("userInfo", member);
                } else {
                    String userAccessToken = jsonObject.getString("access_token");
                    //通过用户AccessToken换取用户信息
                    String userInfoJson = okHttpClient.newCall(
                            new Request.Builder().url("https://api.weixin.qq.com/sns/userinfo?access_token="
                                    + userAccessToken + "&openid=" + openid + "&lang=zh_CN").build()).execute().body().string();
                    com.alibaba.fastjson.JSONObject userInfoJsonObject = com.alibaba.fastjson.JSONObject.parseObject(userInfoJson);
                    Date now = new Date();
                    UmsAdminMember newUserDO = new UmsAdminMember();
                    String nickname = EmojiFilter.filterEmoji(userInfoJsonObject.getString("nickname"));
                    newUserDO.setUsername("M_" + nickname);
                    newUserDO.setNickname(nickname);
                    String avatar = userInfoJsonObject.getString("headimgurl");
                    newUserDO.setAvatar(avatar);
                    newUserDO.setIcon(avatar);
                    newUserDO.setWeixinOpenid(openid);
                    newUserDO.setCreateTime(now);
                    memberMapper.insert(newUserDO);
                    //这一步是为了封装上数据库上配置的默认值
                    token = jwtTokenUtil.generateToken(newUserDO.getUsername());
                    resultObj.put("isNew", true);
                    resultObj.put("userId", newUserDO.getId());
                    resultObj.put("userInfo", newUserDO);
                }
            }
            if (StringUtils.isEmpty(token)) {
                return ApiBaseAction.toResponsFail("登录失败");
            }
            resultObj.put("tokenHead", tokenHead);
            resultObj.put("token", token);
            return resultObj;
        } catch (IOException ie) {
            ie.printStackTrace();
            throw new BusinessMallException(ie.getMessage());
        } catch (ApiMallPlusException e) {
            e.printStackTrace();
            throw new BusinessMallException(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessMallException(e.getMessage());
        }
    }
}

